package cn.pconline.autoclub.web.admin;

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.gelivable.web.Env;
import org.gelivable.web.EnvUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Controller
@RequestMapping("/admin/util")
public class SystemController {
    private static final Logger log = LoggerFactory.getLogger(SystemController.class);
    
    @RequestMapping(value = "/findUriMapMethod.do")
    @ResponseBody
    public String findUriMapMethod(HttpServletRequest request, HttpServletResponse response) {
        final Env env = EnvUtils.getEnv();
        final String uri = env.param("uri", request.getRequestURI());
        return getHandler(request, uri, "GET");
    }

    private String getHandler(HttpServletRequest request, final String uri, String method) {
        final Env env = EnvUtils.getEnv();
        final String fMethod = method;
        String[] beanNames = env.getApplicationContext().getBeanNamesForType(RequestMappingHandlerMapping.class);
        log.info("RequestMappingHandlerMapping: {}", Arrays.toString(beanNames));
        HttpServletRequestWrapper httpServletRequestWrapper = new HttpServletRequestWrapper(request) {
            @Override
            public String getRequestURI() {
                /*String paramUri = super.getParameter("uri");
                if(paramUri != null && !"".equals(paramUri.trim())) {
                    return paramUri;
                }*/
                return uri;
            }
            
            @Override
            public StringBuffer getRequestURL() {
                return new StringBuffer(super.getRequestURL().toString().replace(super.getRequestURI(), uri));
            }
            
            @Override
            public String getServletPath() {
                return super.getServletPath().replace(super.getRequestURI(), uri);
            }
            
            @Override
            public String getMethod() {
                if(fMethod == null || "".equals(fMethod)) {
                    return super.getMethod();
                }
                return fMethod;
            }
        };
        StringBuilder uriMapMethod = new StringBuilder();
        uriMapMethod.append(httpServletRequestWrapper.getRequestURI()).append(": [");
        if(beanNames != null) {
            for(String beanName : beanNames) {
                log.info("beanName: {} ", beanName);
                RequestMappingHandlerMapping mapping = env.getBean(beanName, RequestMappingHandlerMapping.class);
                try {
                    HandlerExecutionChain chain = mapping.getHandler(httpServletRequestWrapper);
                    if(chain != null) {
                        Object handler = chain.getHandler();
                        System.out.println(handler);
                        if(handler instanceof HandlerMethod) {
                            HandlerMethod hm = (HandlerMethod)handler;
                            log.info("{}:{}", hm.getBeanType().getName(),hm);
                            uriMapMethod.append(hm);
                        } else if(handler instanceof org.springframework.web.servlet.mvc.Controller) {
                            org.springframework.web.servlet.mvc.Controller hm = (org.springframework.web.servlet.mvc.Controller)handler;
                            Class<? extends org.springframework.web.servlet.mvc.Controller> hmClass = hm.getClass();
                            log.info("{}:{}", hmClass.getName(), hmClass.getDeclaredMethod("handleRequest", HttpServletRequest.class, HttpServletResponse.class));
                            uriMapMethod.append(hmClass.getDeclaredMethod("handleRequest", HttpServletRequest.class, HttpServletResponse.class));
                        } else {
                            uriMapMethod.append(handler.getClass().getName());
                        }
                        break;
                    }
                } catch (HttpRequestMethodNotSupportedException e) {
                     return getHandler(httpServletRequestWrapper, uri, "POST");
                } catch (Exception e) {
                    log.error("get uri mapping error.", e); 
                }
                /*Map<RequestMappingInfo, HandlerMethod> mapMethods =  mapping.getHandlerMethods();
                if(mapMethods != null) {
                    Iterator<Entry<RequestMappingInfo, HandlerMethod>> iter = mapMethods.entrySet().iterator();
                    while (iter.hasNext()) {
                        Entry<RequestMappingInfo, HandlerMethod> entry = iter.next();
                        RequestMappingInfo key = entry.getKey();
                        HandlerMethod hm = (HandlerMethod)entry.getValue();
                        Method method = hm.getMethod();
                        log.info("{} : {}->{}", key.getPatternsCondition(), key, hm);
                    }
                }*/
            }
        }
        return uriMapMethod.append("]").toString();
    }
}
